//
//  HJAppleICloudStorage.m
//  GoogleLoginICloud
//
//  Created by lx on 2024/1/6.
//

#import "HJAppleICloudStorage.h"


@interface HJAppleICloudStorage()

@property (nonatomic, strong) NSFileCoordinator *coordinator;
@property (nonatomic, copy) NSString *UbiquityContainerIdentifiers;

@end


@implementation HJAppleICloudStorage

- (instancetype)init {
    if (self = [super init]) {
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleUbiquityIdentityDidChangeNotification:) name:NSUbiquityIdentityDidChangeNotification object:nil];
    }
    return self;
}

+ (void)setUpKeyValueICloudStoreWithKey:(NSString *)key value:(NSString *)value {
    NSUbiquitousKeyValueStore *keyValueStore = [NSUbiquitousKeyValueStore defaultStore];
    [keyValueStore setObject:value forKey:key];
    [keyValueStore synchronize];
}

+ (void)setUpKeyValueICloudStoreWithBlock:(void (^__nullable)(NSUbiquitousKeyValueStore *keyValueStore))setKeyValueBlock {
    NSUbiquitousKeyValueStore *keyValueStore = [NSUbiquitousKeyValueStore defaultStore];
    if (setKeyValueBlock) {
        setKeyValueBlock(keyValueStore);
    }
    [keyValueStore synchronize];
}

+ (NSString *)getKeyValueICloudStoreWithKey:(NSString *)key {
    NSUbiquitousKeyValueStore *keyValueStore = [NSUbiquitousKeyValueStore defaultStore];
    NSString *testString = [keyValueStore objectForKey:key];
    return testString;
}

- (NSFileCoordinator *)coordinator {
    if (!_coordinator) {
        _coordinator = [[NSFileCoordinator alloc] init];
    }
    return _coordinator;
}

//获取地址
+ (NSURL *)getUbiquityContauneURLWithFileName:(NSString *)fileName {
    
    if (![[NSFileManager defaultManager] ubiquityIdentityToken]) {
        return nil;
    }
    
    NSURL *ubiquityURL = [[NSFileManager defaultManager] URLForUbiquityContainerIdentifier:nil];
    if(!ubiquityURL) {
        return nil;
    }
    
    NSLog(@"ubiquityURL = %@", ubiquityURL);
    
    NSURL *URLWithFileName = [ubiquityURL URLByAppendingPathComponent:@"Documents"];
    URLWithFileName = [URLWithFileName URLByAppendingPathComponent:fileName];
    return URLWithFileName;
}

- (void)writeWithData:(NSData *)data fileName:(NSString *)fileName completion:(void (^__nullable)(NSError * _Nullable error))completion {
    
    NSURL *targetURL = [HJAppleICloudStorage getUbiquityContauneURLWithFileName:fileName];
    if (!targetURL) {
        !completion ?: completion([NSError errorWithDomain:@"HJAppleICloudStorageError" code:-1001 userInfo:@{NSLocalizedFailureReasonErrorKey: @"iCloud is unavailable"}]);
        return;
    }
    
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        
        NSError *coordinationError = nil;
        
        [self.coordinator coordinateWritingItemAtURL:targetURL options:NSFileCoordinatorWritingForDeleting error:&coordinationError byAccessor:^(NSURL *newURL) {
            
            if (coordinationError) {
                dispatch_async(dispatch_get_main_queue(), ^{
                    !completion ?: completion(coordinationError);
                });
                return;
            }
            
            NSError *writeError = nil;
            @try {
                [data writeToURL:newURL options:NSDataWritingAtomic error:&writeError];
            } @catch (NSException *exception) {
                writeError = [NSError errorWithDomain:@"HJAppleICloudStorageError" code:-1001 userInfo:@{NSLocalizedFailureReasonErrorKey: exception.reason}];
            }
            
            dispatch_async(dispatch_get_main_queue(), ^{
                !completion ?: completion(writeError);
            });
        }];
    });
}


- (void)readWithFileName:(NSString *)fileName completion:(void (^__nullable)(NSData * _Nullable fileData, NSError * _Nullable error))completion {
    
    NSURL *targetURL = [HJAppleICloudStorage getUbiquityContauneURLWithFileName:fileName];
    if (!targetURL) {
        !completion ?: completion(nil, [NSError errorWithDomain:@"HJAppleICloudStorageError" code:-1001 userInfo:@{NSLocalizedFailureReasonErrorKey: @"iCloud is unavailable"}]);
        return;
    }
    NSLog(@"targetURL = %@", targetURL);
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        
        NSError *coordinationError = nil;
        
        [self.coordinator coordinateReadingItemAtURL:targetURL options:0 error:&coordinationError byAccessor:^(NSURL *newURL) {
            
            if (coordinationError) {
                dispatch_async(dispatch_get_main_queue(), ^{
                    completion(nil, coordinationError);
                });
                return;
            }
            
            NSError *writeError = nil;
            NSData *fileData = nil;
            
            @try {
                fileData = [NSData dataWithContentsOfURL:newURL];
            } @catch (NSException *exception) {
                writeError = [NSError errorWithDomain:@"HJAppleICloudStorageError" code:-1001 userInfo:@{NSLocalizedFailureReasonErrorKey: exception.reason}];
            }
            
            dispatch_async(dispatch_get_main_queue(), ^{
                completion(fileData, writeError);
            });
        }];
    });
}


- (void)downloadWithFileName:(NSString *)fileName destinationURL:(NSURL *)destinationURL completion:(void (^__nullable)(NSError * _Nullable error))completion {
    
    NSURL *targetURL = [HJAppleICloudStorage getUbiquityContauneURLWithFileName:fileName];
    if (!targetURL) {
        !completion ?: completion([NSError errorWithDomain:@"HJAppleICloudStorageError" code:-1001 userInfo:@{NSLocalizedFailureReasonErrorKey: @"iCloud is unavailable"}]);
        return;
    }
    
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        
        NSError *coordinationError = nil;
        
        [self.coordinator coordinateReadingItemAtURL:targetURL options:0 error:&coordinationError byAccessor:^(NSURL *newURL) {
            
            if (coordinationError) {
                dispatch_async(dispatch_get_main_queue(), ^{
                    !completion ?: completion(coordinationError);
                });
                return;
            }
            
            NSError *writeError = nil;
            NSData *fileData = [NSData dataWithContentsOfURL:newURL];

            @try {
                [fileData writeToURL:destinationURL options:NSDataWritingAtomic error:&writeError];
            } @catch (NSException *exception) {
                writeError = [NSError errorWithDomain:@"HJAppleICloudStorageError" code:-1001 userInfo:@{NSLocalizedFailureReasonErrorKey: exception.reason}];
            }
            
            dispatch_async(dispatch_get_main_queue(), ^{
                !completion ?: completion(writeError);
            });
        }];
    });
}

- (void)deleteWithFileName:(NSString *)fileName completion:(void (^__nullable)(NSError * _Nullable error))completion {
    
    NSURL *targetURL = [HJAppleICloudStorage getUbiquityContauneURLWithFileName:fileName];
    if (!targetURL) {
        !completion ?: completion([NSError errorWithDomain:@"HJAppleICloudStorageError" code:-1001 userInfo:@{NSLocalizedFailureReasonErrorKey: @"iCloud is unavailable"}]);
        return;
    }
    
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        
        NSError *coordinationError = nil;
        
        [self.coordinator coordinateWritingItemAtURL:targetURL options:NSFileCoordinatorWritingForDeleting error:&coordinationError byAccessor:^(NSURL *newURL) {
            
            if (coordinationError) {
                dispatch_async(dispatch_get_main_queue(), ^{
                    !completion ?: completion(coordinationError);
                });
                return;
            }
            
            NSError *deleteError;
            [[NSFileManager defaultManager] removeItemAtURL:newURL error:&deleteError];
 
            dispatch_async(dispatch_get_main_queue(), ^{
                !completion ?: completion(deleteError);
            });
        }];
    });
}

- (void)handleUbiquityIdentityDidChangeNotification:(NSNotification *)notification {
     NSLog(@"iCloud identity changed");
    // 检查当前的 iCloud 权限状态
    if ([[NSFileManager defaultManager] ubiquityIdentityToken]) {
        NSLog(@"iCloud is enabled");
    } else {
        NSLog(@"iCloud is disabled");
    }
}

- (void)dealloc {
    [[NSNotificationCenter defaultCenter] removeObserver:self name:NSUbiquityIdentityDidChangeNotification object:nil];
}

@end
